package com.yuanchu.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.search.client.FeignOrderClient;
import com.yuanchu.search.dto.QueryOrderParamsDto;
import com.yuanchu.search.entity.YoshopOrderRefundEntity;
import com.yuanchu.search.service.OrderRefundService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.yuanchu.search.service.impl.OrderServiceImpl.convertStringToSeconds;

/**
 * @version: 1.0
 * @Author: adan
 * @description:
 * @date: 2024-03-02 1:58
 */
@Slf4j
@Service
public class OrderRefundServiceImpl implements OrderRefundService {

    @Resource
    private RestHighLevelClient client;
    @Resource
    private FeignOrderClient feignOrderClient;

    @Override
    public PageResult<YoshopOrderRefundEntity> queryStoreOrderRefunds(QueryOrderParamsDto param) {
        Integer searchType = param.getSearchType(); // 搜索类型
        String searchValue = param.getSearchValue();    // 搜索值
        Integer refundType = param.getRefundType(); // 物流方式
        Integer refundStatus = param.getRefundStatus();   // 支付方式

        long betweenTimeStart = convertStringToSeconds(param.getBetweenTimeStart());  // 时间区间
        long betweenTimeEnd = convertStringToSeconds(param.getBetweenTimeEnd());
        // 设置索引
        SearchRequest searchRequest = new SearchRequest("yuanchu_order_refund");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建条件查询
        BoolQueryBuilder boolQueryBuilder = buildBasicQuery(searchType, searchValue, refundType,
                refundStatus, betweenTimeStart, betweenTimeEnd);

        // 分页
        Integer pageNo = param.getPage();
        Integer pageSize = param.getPageSize();
        int start = (pageNo - 1) * pageSize;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(Math.toIntExact(pageSize));
        // 布尔查询
        searchSourceBuilder.query(boolQueryBuilder)
                .sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
        // 请求搜索
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("订单搜索异常：{}", e.getMessage());
            return PageResult.formatPageResult(Collections.emptyList(), pageNo, pageSize);
        }

        // 结果集处理
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        // 记录总数
        TotalHits totalHits = hits.getTotalHits();
        // 数据列表
        List<YoshopOrderRefundEntity> list = new ArrayList<>();

        for (SearchHit hit : searchHits) {
            String sourceAsString = hit.getSourceAsString();
            YoshopOrderRefundEntity orderRefund = JSON.parseObject(sourceAsString, YoshopOrderRefundEntity.class);
            orderRefund.setCreateTime(DateFormatUtils.formatDatetime(orderRefund.getCreateTime()));
            orderRefund.setOrderNo(orderRefund.getOrderData().getOrderNo());
            orderRefund.setAddress(null);
            list.add(orderRefund);
        }
        return PageResult.formatPageResult(list, pageNo, pageSize, totalHits.value);
    }

    @Override
    public YoshopOrderRefundEntity getStoreOrderDetail(Integer orderRefundId) {
        // 1、从es查询
        // 设置索引
        // 1.准备Request
        GetRequest request = new GetRequest("yuanchu_order_refund", String.valueOf(orderRefundId));
        // 2.发送请求，得到响应
        GetResponse response = null;
        try {
            response = client.get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 3.解析响应结果
        String json = response.getSourceAsString();
        YoshopOrderRefundEntity orderSearch = JSON.parseObject(json, YoshopOrderRefundEntity.class);
        if (orderSearch != null){
            orderSearch.setCreateTime(DateFormatUtils.formatDatetime(orderSearch.getCreateTime()));
            return orderSearch;
        }
        // 2、调用接口查询
        return feignOrderClient.queryOrderRefundDetail(orderRefundId);

    }

    private BoolQueryBuilder buildBasicQuery(Integer searchType, String searchValue, Integer refundType, Integer refundStatus, long betweenTimeStart, long betweenTimeEnd) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 关键字
        if (StringUtils.isNotEmpty(searchValue)) {
            // 搜索类型
            if (searchType == 10) {
                // 订单号
                boolQueryBuilder.must(QueryBuilders.matchQuery("orderData.orderNo", searchValue));
            } else if (searchType == 20) {
                // 会员昵称，匹配关键字
                boolQueryBuilder.must(QueryBuilders.matchQuery("user.nickName", searchValue));
            } else if (searchType == 30) {
                // 会员id
                boolQueryBuilder.must(QueryBuilders.termQuery("userId", searchValue));
            }
        }
        // 售后类型(10退货退款 20换货)
        if (refundType != null && refundType > 0) {
            boolQueryBuilder.must(QueryBuilders.termQuery("type", refundType));
        }
        // 售后单状态(0进行中 10已拒绝 20已完成 30已取消)
        if (refundStatus != null && refundStatus > 0) {
            boolQueryBuilder.must(QueryBuilders.termQuery("status", refundStatus));
        }
        // 时间区间
        if (betweenTimeStart > 0 && betweenTimeEnd > 0) {
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("createTime");
            rangeQuery.lte(betweenTimeEnd);
            rangeQuery.gte(betweenTimeStart);
            boolQueryBuilder.filter(rangeQuery);
        }
        return boolQueryBuilder;
    }
}
